 (function(){
 "use strict";
 /**
 * zhx.multiCTC
 *
 * Description
 *
 * Author : Vicco Wang
 * Date : 05/02/2017
 *
 * Dependency core plugins:
 *
 * jQuery
 * jQuery UI
 * AngularJS
 * ui.sortable
 * ui.bootstrap.contextmenu
 * jquery-mousewheel
 * custom-scrollbar
 *
 *
 */
var ctcApp = angular.module('zhx.multi.ctc',[
                'ui.sortable',
                'ui.bootstrap.contextMenu',
                'zhx.multi.ctc.template'
            ]);

/**
 * Provider 服务
 */
ctcApp.provider('zhx.multi.ctc',function(){

    var config = {
    };

    this.config = function(userCustomConfig){
        config = angular.merge({}, config, userCustomConfig);
    };

    this.$get = function(){
        return {
            getConfig : function(){
                return config;
            }
        }
    }

});

/**
 * 通用组件服务
 */
ctcApp.factory('zhx.multi.ctc.util',function(){

    var service = {};

    /**
     * 判断数组对象中是否存在相同KEY值的对象
     * @param srcObject        原对象
     * @param distArray        要比较的数组
     * @param key              要比较的KEY
     * @returns {boolean}      是否存在相同
     */
    service.isObjectArrayContainSame = function(srcObject, distArray, key){
        if( !angular.isObject(srcObject) || !angular.isArray(distArray) ) return;
        for( var i = 0; i < distArray.length; i++ ){
            var distArrObject = distArray[i];
            if( srcObject[key] === distArrObject[key] ) {
                return true;
            }
        }
        return false;
    };

    return service;

});

/**
 * 直线图CTC 服务
 */
ctcApp.factory('zhx.multi.ctc.service',['$compile','$timeout','$q',function($compile,$timeout,$q){

    var service = {};

    /**
     * 直线图默认配置参数
     */
    service.getOptions = function(){

        var customOptions = {
            //lines Object Data
            ctcData : null,
            //must containing lineId
            busData : {
                resData : null,
                lineId : null
            },
            isColumnScreen : false,
            lineKeyMap : {},
            busKeyMap : {}
        };

        return customOptions;
    };

    /**
     * 直线图字段映射表
     * @param opts
     * @returns {{lineKeyMap, busKeyMap}}
     */
    service.getKeyMap = function(opts){
        var lineKeyMap = {
                lineIdKey           : 'lineId',
                lineNameKey         : 'lineName',
                upStationLineKey	: 'upStationList' ,
                downStationLineKey	: 'downStationList' ,
                stationIdKey		: 'station_uuid' ,
                positionKey			: 'position',
                stationNameKey		: 'station_name' ,
                statDistanceKey		: 'line_station_start_distance' ,
                isShowKey			: 'line_station_is_show'
            },
            busKeyMap = {
                lineTypeKey			: 'lineType',
                busIdKey			: 'busUuid',
                devIdKey			: 'devUuid',
                busNoKey			: 'busPlate',
                rateKey 			: 'rate',
                rateStationKey 		: 'rateStation',
                stationSequenceKey 		: 'stationSequence',
                driverNameKey		: 'drv_name',
                busStatusKey		: 'status',
                busSpeedKey			: 'busSpeed',
                fullLoadRateKey		: 'fullLoadRate',
                alarmMsgKey			: 'alarmsname',
                busShiftKey			: 'shift',
                busTripKey			: 'trip',
                nextStationKey		: 'nowStation',
                operationKey		: 'operation',
                planTimeKey			: 'planTime',
                startTimeKey		: 'realTime',
                forecastTimeKey		: 'forecastTime',
                forecastMsgKey		: 'forecastMsg',
                tripDateKey			: 'tripDate',
                lastStationNumKey	: 'lastStationNum',
                lastUpdateTimeKey	: 'lastUpdateTime',
                nextTripTimeKey     : 'nextTripTime',
                toFinalStationNumKey : 'toFinalStationNum',
                //以下为车辆状态
                inStationKey        : 'inStation',                       //进出站标识
                delayDepartureKey   : 'delayDeparture',                  //延迟发车
                aheadDepartureKey   : 'aheadDeparture',                  //提前发车
                overSpeedKey        : 'overSpeed',                       //超速
                positionOvertakeKey : 'positionOvertake',                //超车标识
                allAlarmsKey        : 'allAlarms'                        //（6：手动报警）
            },
            keyMap = {
                lineKeyMap : angular.extend( {}, lineKeyMap, opts.lineKeyMap ),
                busKeyMap  : angular.extend( {}, busKeyMap , opts.busKeyMap )
            };

        return keyMap;
    };

    /**
     * 挑边儿方法~ 非左即右 :p
     * @param ctcArray
     * @param isColumnScreen
     * @returns {*}
     */
    service.getTheCorrectSide = function(ctcArray,isColumnScreen){
        if( !isColumnScreen ) return 'western';
        return ctcArray.western.length > ctcArray.eastern.length ? 'eastern' : 'western';
    };

    /**
     * 重构线路站点[非车辆]位置为百分比
     * @param stationLineData       站点信息
     * @param lineKeyMap            线路字段映射表
     * @returns {*}
     */
    service.getRenderStationLineData = function( stationLineData, lineKeyMap ){
        var i = 0,stationLineDataLen = stationLineData.length;
        if( !stationLineDataLen ) return;
        for( ; i < stationLineDataLen; i++ ){
            var station = stationLineData[i];
            station.__relativePos = parseFloat( station[lineKeyMap.positionKey] * 100 ).toFixed(1) + '%';
        }
        return stationLineData;
    };

    /**
     * 将原始的车辆数据进行重构
     * @param updateBus         需要重构的车辆原始数据
     * @param busKeyMap         车辆字段映射表
     * @param busDisplayKey     显示车牌还是子编号判断依据
     * @param onLineBusArr      需要更新对应的数组, 一般为 上下行,待发区或者离线和停运数组其中的一个
     * @param elementWrapper    直线图DOM父节点
     * @returns {*}
     */
    service.getThePreRenderDataOfBus = function( updateBus, busKeyMap, busDisplayKey, onLineBusArr, elementWrapper ){

        if( !angular.isObject( updateBus ) ) return;
        //获取当前线路总宽度PX,仅用来计算相对位置
        var busLineWidth = parseInt( elementWrapper.find('.ctc-linear-line').outerWidth() );
        //设置一个位置渲染百分比

        updateBus.ralativeRate = updateBus[busKeyMap.rateKey];
        updateBus.__relativePos = (updateBus[busKeyMap.rateKey] * 100).toFixed(1) + '%';

        //设置像素级的相对位置，此位置不做渲染用，仅仅用来判断车辆位置是否重叠之使用
        updateBus.__relativePosPx = parseInt( updateBus.ralativeRate * busLineWidth );
        //默认车辆渲染在-6像素位置（初始高度）
        updateBus.__relativeTop = -6;
        //车辆缩略号显示, 车牌号(排除字符串前两位,例如 陕A ) / 自编号或其他号码
        var updateBusDisKey = updateBus[busDisplayKey];
        //默认什么也不显示
        updateBus.__smallNo = null;
        if( !angular.isUndefined(updateBusDisKey) && updateBusDisKey !== '' ){
            //判断是否显示车牌号还是其他字段, 车牌号默认自动截取前两位
            updateBus.__smallNo = busDisplayKey === busKeyMap.busNoKey ? updateBusDisKey.substring(2) : updateBusDisKey;
        }

        var onLineBusArrLen = onLineBusArr.length;

        /**
         * 修正位置重叠，循环当前线路（上行或下行）上所有车辆对象，进行比对。如果位置相差16像素以内则表示重叠（保证在同一高度下重叠，不同位置高度不需要判断是否重叠）
         * 重叠的车高度会递增50像素
         */
        for( var j = 0; j < onLineBusArrLen; j++ ){
            var arrBus = onLineBusArr[j];
            arrBus.__relativeTop = -6;
            for( var t = 0; t < onLineBusArrLen; t++ ){
                var distBus = onLineBusArr[t];
                //不和自己比较
                if( arrBus[busKeyMap.busIdKey] === distBus[busKeyMap.busIdKey] ) break;
                //计算数组中两辆车之间的位置
                var distance = Math.abs( parseInt(arrBus.__relativePosPx) - parseInt(distBus.__relativePosPx) );
                //判断待更新车辆是否拥有侧面图标,拥有图标的后面计算重叠应该把图标宽度计算在内
                var isBusHasIcon = ( arrBus.busStatusIcon !== "" || distBus.busStatusIcon !== "" ) && ( !angular.isUndefined(arrBus.busStatusIcon) || !angular.isUndefined(distBus.busStatusIcon) ) ;
                //如果车辆有图标则应该为25像素宽度
                var busRawWidth = isBusHasIcon ? 30 : 17;
                if( distance < busRawWidth && arrBus.__relativeTop === distBus.__relativeTop ){
                    //上行向上位移,下行向下位移
                    arrBus[busKeyMap.lineTypeKey] === "1" ? arrBus.__relativeTop -= 17 :  arrBus.__relativeTop += 17;
                }
            }

        }

        return updateBus;

    };

    /**
     * 在某些情况下,比如窗口缩放时,需要重新计算直线图上车辆的相对位置.
     * 因为相对位置是以像素为单位进行的内部计算,所以在每次窗口缩放后,需要重新进行计算.
     * 该方法一般在直线图父指令中进行绑定
     * @param  {[type]} busArrayObject [description]
     * @param  {[type]} busKeyMap      [description]
     * @param  {[type]} elementWrapper [description]
     */
    service.updateOnlineBusPos = function(busArrayObject,busKeyMap, elementWrapper){

        angular.forEach(busArrayObject,function(busArray, arrName){
            //只计算直线图上车辆的位置
            if( arrName === 'upLineBus' || arrName === 'downLineBus' ){
                var busLineWidth = parseInt( elementWrapper.find('.ctc-liear-line').outerWidth() ),
                    i, busArrLen = busArray.length;
                for( i = 0; i < busArrLen; i++){
                    var bus = busArray[i];
                    //设置像素级的相对位置，此位置不做渲染用，仅仅用来判断车辆位置是否重叠之使用
                    bus.__relativePosPx = parseInt( bus.ralativeRate * busLineWidth );
                }
                // console.log('重新计算位置.');
            }
        });

    };

    /**
     * 创建一个弹出层，共日历扩展使用（左右键点击等等）
     * @param  {[type]} options      [layer options]
     */
    service.createLayer = function(options){

        var normalConfig = {
            event : window.event,           //[window事件对象]
            dom : '',                       //[一个HTML字符串，可以直接添加进弹出层中]
            scope : null,                   //[作用域，传递了该作用域后则会进行Angular编译]
            isolate : true,                 //[是否为独立作用域，如果使用了独立作用域，则在移除弹出层时会自动销毁该作用域]
            autoClose : true,               //是否自动关闭
            addCallBack : function(){},     //打开后回调
            removeCallBack : function(){}   //移除后回调
        };

        var cfg = angular.extend({}, normalConfig, options );

        var ev = cfg.event || window.event,
            rect = ev.target.getBoundingClientRect(),
            x = rect.left,
            y = rect.top,
            dw = document.documentElement.clientWidth,
            dh = document.documentElement.clientHeight,
            domClassName = 'zhx-multi-ctc-layer',
            layers = angular.element('.' + domClassName);

        var isCreated = !!layers.length;

        var __createLayer = function(){
            return angular.element('<div class='+ domClassName +'></div>');
        };

        var __renderLayer = function(layer){
            if( isCreated ){
                layer.empty();
            }
            //将DOM模板放入LAYER中
            cfg.dom && layer.append(cfg.dom);
            //如果启用编译，则使用angular进行编译处理
            cfg.scope && $compile(layer)(cfg.scope);
            //声明一个移除LAYER方法
            cfg.scope.removeLayer = function(){
                layer.velocity({
                    scale : 0,
                    opacity : 0
                },{
                    duration : 120,
                    complete : function(){
                        $timeout(function(){
                            layer.remove();
                            cfg.isolate && cfg.scope.$destroy();
                            angular.element('body').off('click',cfg.scope.removeLayer);
                            cfg.removeCallBack.call(this,event,cfg.scope,layer);
                        });
                    }
                });
            };

            //绑定一个接收事件，如果外部手动需要关闭，可以传递该事件关闭当前layer
            if( cfg.autoClose || !angular.isUndefined(cfg.autoClose) ){
                cfg.scope.$on('zhx.ctc.layer.close',function(ev,res){
                    cfg.scope.removeLayer();
                });
            } else {
                layer.on('click',function(event){
                    var ev = event || window.event;
                    ev.stopPropagation();
                });
            }

            //给BODY绑定一个移除LAYER的事件
            angular.element('body').on('click',cfg.scope.removeLayer);

            //为LAYER设定具体弹出位置
            $timeout(function(){

                var layerHeight = layer.outerHeight() || layer[0].clientHeight,
                    layerWidth = layer.outerWidth() || layer[0].clientWidth,
                    offsetHeight = dh - layerHeight,
                    offsetWidth = dw - layerWidth;

                //防止LAYER溢出屏幕
                layer.css({ top : offsetHeight - y < 10 ? offsetHeight - 10 : y + 15 , left : offsetWidth - x < 10 ?  offsetWidth - 10 : x + 15 });
                layer.velocity({
                    scale : 1,
                    opacity : .96
                }, 120 );

                cfg.addCallBack.call(this,event,cfg.scope,layer);

            });

            return layer;

        };


        if( !isCreated ) var layer = __createLayer();

        return __renderLayer( layer || layers );

    };

    return service;

}]);

/**
 *
 * 直线图CTC 父控制器 Main Controller
 */
ctcApp.controller('zhx.multi.mainCtrl', ['$scope','zhx.multi.ctc.service','zhx.multi.ctc.util',function($scope,ctcService,ctcUtil){

    var vm = this;

    //基于CTC的配置项
    var options = angular.extend({}, ctcService.getOptions(), $scope,options );

    //KEYMAP mirrors
    $scope.keyMap = ctcService.getKeyMap(options);
    $scope.lineKeyMap = $scope.keyMap.lineKeyMap;
    $scope.busKeyMap  = $scope.keyMap.busKeyMap;
    //全屏状态单个直线图DOM高度
    $scope.fullScreenCTCSize = 270;
    //分屏状态单个直线图DOM高度
    $scope.smallScreenCTCSize = 250;
    //左右分屏线路数据对象数组
    $scope.ctcArray = {
        western : [],    //左侧列表线路
        eastern : []     //右侧列表线路
    };
    //默认不分屏显示
    $scope.isColumnScreen = options.isColumnScreen || false;
    //根据lineType 和 status字段数据获取对应直线图的数组,这里是一个简单的映射关系
    var busArrMap = {
        "1" : {
            "0" : "upLineBus",
            "1" : "upReadyBus",
            "234567" : "upNonServiceBus",
            "8" : "offLineBus",
            "9" : "stopServiceBus"
        },
        "2" : {
            "0" : "downLineBus",
            "1" : "downReadyBus",
            "234567" : "downNonServiceBus",
            "8" : "offLineBus",
            "9" : "stopServiceBus"
        }
    };
    //根据收到的线路数据填入对应分屏线路数组中
    vm.setCtcArray = function( lineArray, keyMap ){
        if( !lineArray.length ) return;

        for( var i = 0; i < lineArray.length; i++ ){
            var lineObject = lineArray[i];
            var direction = ctcService.getTheCorrectSide( $scope.ctcArray, $scope.isColumnScreen ),
                distArray = $scope.ctcArray[direction];
            var concatArray = $scope.ctcArray.western.concat($scope.ctcArray.eastern);
            //判断准备插入的线路是否已经存在,页面上的线路具有唯一性
            var hasTheSame = ctcUtil.isObjectArrayContainSame(lineObject, concatArray, keyMap.lineKeyMap.lineIdKey );
            //插入对应数组中, western or eastern
            !hasTheSame && distArray.push( lineObject );
        }
    };

    vm.getKeyMap = function(){
        return $scope.keyMap;
    };

    vm.getBusData = function(){
        return $scope.options.busData;
    };

    vm.getColumnScreenState = function(){
        return $scope.isColumnScreen;
    };
    /**
     * 新建与更新车辆数据额
     * @param busObject
     * @param busAttribution
     * @param ctcWrapperElement
     */
    vm.updateBus = function( busObject, busAttribution, ctcWrapperElement ){
        var busKeyMap = $scope.keyMap.busKeyMap,
            busLineType = busObject[busKeyMap.lineTypeKey],
            busId  = busObject[busKeyMap.busIdKey],
            status = busObject[busKeyMap.busStatusKey];

        var willUpdateArrObject;

        //更新数据以busID为基准进行检测，如果一样则更新，不一样则添加
        var __updateInArray = function(arr){
            if(!arr){
                return;
            }
            var flag = false, arrLen = arr.length;
            //检查更新车辆与数组进行比对
            for( var i = 0 ; i < arrLen; i++ ){
                if( busId === arr[i][busKeyMap.busIdKey] ){
                    //切换线路后，移除数组中的元素，实现删除
                    if(busObject.isDeleted){
                        arr.splice(i,1);
                        flag = true;
                        break;
                    }
                    //也许需要merge or extend ?
                    arr.splice(i,1,busObject);
                    flag = true;
                    break;
                }
            }

            //全部状态车辆数组循环,与当前需要更新的车辆进行比对,如果状态不一样且ID一样,则从该数组中移除
            angular.forEach( busAttribution, function(busArr,arrName){

                if( !busArr.length ) return;

                for( var i = 0 ; i < busArr.length; i++ ){
                    var bus = busArr[i];
                    if( busId === bus[busKeyMap.busIdKey] ){
                        if( status !== bus[busKeyMap.busStatusKey] || busLineType !== bus[busKeyMap.lineTypeKey] ){
                            $scope.busAttribution[arrName].splice( i , 1 );
                        }
                    }

                }

            });

            if( flag ) return;
            //如果为新车,则直接添加至对应数组中
            arr.push(busObject);

        };

        //获取需要更新的数组名,即车辆属于哪个数组
        var statusTypeName = null;
        angular.forEach(busArrMap,function(statusObj,lineType){
            if( busLineType === lineType){
                angular.forEach( statusObj,function(stsName, sts){
                    if( sts.indexOf( status ) !== -1  ){
                        statusTypeName = stsName;
                    }
                })
            }
        });

        willUpdateArrObject = busAttribution[statusTypeName];
        //更新对应数组中的车辆
        __updateInArray( willUpdateArrObject );

        //如果是线上车辆,则还需要计算车辆相对位置数据
        if( status === "0" ) ctcService.getThePreRenderDataOfBus( busObject, $scope.busKeyMap, 'busNum', willUpdateArrObject , ctcWrapperElement );
    };

    //监控外部传入的线路数据
    $scope.$watch('options.ctcData',function(array){
        if( array ){
            vm.setCtcArray( array, $scope.keyMap  );
        }
    });

    /**
     * 监控分屏状态,总布局控制
     * @param isColumned    是否启用了分屏模式
     */
    $scope.$watch('isColumnScreen', function(isColumned){
        //全屏切换至分屏
        if( isColumned ){
            var tempArray = angular.copy($scope.ctcArray.western);
            $scope.ctcArray.western = [];
            vm.setCtcArray(tempArray,$scope.keyMap );
            //分屏切换至全屏
        } else {
            /**
             * 分屏切换回全屏应按照左1条右1条顺序插入回western列
             * example:  western  1 5 3     eastern 2 4
             * result : 12543
             */
            var westArr = angular.copy($scope.ctcArray.western),
                eastArr = angular.copy($scope.ctcArray.eastern),
                maximumArr = westArr.length > eastArr.length ? westArr : eastArr,
                minimumArr = westArr.length > eastArr.length ? eastArr : westArr,
                remainder =  maximumArr.length === $scope.ctcArray.western.length ? 0 : 1;  //计算余数取值
            for( var i = 0; i < maximumArr.length; i++ ){
                if( i%2 === remainder ){
                    if( minimumArr.length ){
                        maximumArr.splice(i,0, minimumArr[0]);  //insert the object at the correct position
                        minimumArr.splice(0,1); //remove the corresponding object
                    }
                }
            }
            //reset ctcArray
            $scope.ctcArray.western = [];
            $scope.ctcArray.eastern = [];
            //set result
            $scope.ctcArray.western = maximumArr;

        }

        //分不分屏决定CTC高度是多少
        $scope.ctcSectionHeight = $scope.isColumnScreen ? $scope.smallScreenCTCSize : $scope.fullScreenCTCSize;

    })

}]);

/**
 * 直线图CTC父指令,该指令只负责控制框架公共区域交互逻辑,例如拖拽和自定义滚动条等的初始化工作;
 */
ctcApp.directive('zhxMultiCtc',['$document','$timeout',function($document,$timeout){
    return{
        restrict : 'E',
        scope : {
            options : '='
        },
        replace : true,
        controller : 'zhx.multi.mainCtrl',
        link : function( scope, tElement, tAttrs ){

            //initial ui-sortable settings
            scope.sortOptions = {
                // axis : scope.isColumnScreen ? false : 'y',
                items : '.ctc-section',
                handle : '.ctc-header',
                connectWith : '.ctc-section-wrapper',
                forcePlaceholderSize : true,
                distance : 10,
                placeholder : 'ctc-section-placeholder',
                tolerance : 'pointer',
                //events
                update : function( event, ui ){
                    /**
                     * 当一侧数据被拖拽清空时,应自动全屏显示
                     * @type {*}
                     */
                    var isArrayEmpty = ( !scope.ctcArray.western.length || !scope.ctcArray.eastern.length ) && scope.isColumnScreen;
                    if( isArrayEmpty ){
                        if( scope.ctcArray.eastern.length ){
                            scope.ctcArray.western = angular.copy( scope.ctcArray.eastern );
                            scope.ctcArray.eastern = [];
                        }
                        scope.isColumnScreen = !scope.isColumnScreen;
                    }
                }
            };

            //initial custom scroll bar after angular loaded
            scope.$evalAsync(function(){
                tElement.find(".ctc-section-wrapper").mCustomScrollbar({
                    axis:"y", // horizontal scrollbar
                    theme:"minimal-dark",
                    autoHideScrollbar : true,
                    scrollInertia : 200
                });
            });

            //分屏按钮事件,切换分屏状态
            scope.columnScreen = function(){
                scope.isColumnScreen = !scope.isColumnScreen;
            };

        },
        templateUrl : 'zhx.multi.ctc.tpl.vicco'
    }
}]);

/**
 *直线图CTC控制器
 */
ctcApp.controller('zhx.multi.subCtrl',['$scope',function($scope){

    /**
     * 每个直线图都会有一套该数组进行对应
     * 该数组直接对应模板中的数据
     */
    $scope.busAttribution = {
        //上行线上车辆
        upLineBus : [],
        //下行线上车辆
        downLineBus : [],
        //上行待发车辆数组
        upReadyBus : [],
        //下行待发车辆数组
        downReadyBus : [],
        //上行非运营数组
        upNonServiceBus : [],
        //下行非运营数组
        downNonServiceBus : [],
        //离线车辆数组
        offLineBus : [],
        //停运车辆数组
        stopServiceBus : []
    };

    /**
     * 通过KEY值来获取对应的名称
     * @param key
     * @returns {*}
     */
    $scope.getBusAttrName = function(key){
        if( $scope.busAttribution[key] ){
            switch(key){
                case 'upLineBus' :
                    return '上行车辆';
                case 'downLineBus':
                    return '下行车辆';
                case 'upReadyBus':
                    return '上行待发区';
                case 'downReadyBus':
                    return '下行待发区';
                case 'upNonServiceBus':
                    return '上行非运营';
                case 'downNonServiceBus':
                    return '下行非运营';
                case 'offLineBus':
                    return '离线车辆';
                case 'stopServiceBus':
                    return '停运车辆';
            }
        }
        return false;
    }

}]);
/**
 * 直线图CTC 指令,每个直线图中的线路数据,车辆数据都为独立数组对象保存;
 */
ctcApp.directive('subCtc',['$timeout','$templateCache','zhx.multi.ctc.service',function($timeout,$templateCache,ctcService){
    return{
        restrict : 'E',
        scope : {
            options : '='
        },
        replace : true,
        require : '^?zhxMultiCtc',
        controller :'zhx.multi.subCtrl',
        link : function( scope, tElement, tAttrs, mainCtroller ){

            /**
             * 为每个直线图作用域绑定一些必要属性
             */
            //KeyMap部分
            scope.keyMap = mainCtroller.getKeyMap();
            //线路站点KeyMap
            scope.lineKeyMap = scope.keyMap.lineKeyMap;
            //车辆KeyMap
            scope.busKeyMap  = scope.keyMap.busKeyMap;
            //线路名称
            scope.lineName = scope.options[scope.lineKeyMap.lineNameKey];
            //线路Id
            scope.lineId = scope.options[scope.lineKeyMap.lineIdKey];
            //上行站点数据
            scope.upStationList = ctcService.getRenderStationLineData( scope.options[scope.lineKeyMap.upStationLineKey] , scope.lineKeyMap);
            //下行站点数据
            scope.downStationList = ctcService.getRenderStationLineData( scope.options[scope.lineKeyMap.downStationLineKey] , scope.lineKeyMap);

            /**
             * 待发区,非运营,停运与离线列表菜单构建;
             *
             */
            scope.stateMenuOptions = function(busAttrKey){
                var menuArray = [];
                /**
                 * 二级菜单数据,悬浮车后出现的菜单
                 *
                 * $itemScp         菜单所在作用域
                 * $parentItem      上级菜单的对象
                 */
                var secStepMenu = [
                    ['打电话' ,function($itemScp, $parentItem){
                        //bus data;
                       console.log( $parentItem.data );
                    },_canBeEnabled],null,
                    ['强制非运营' ,function($itemScp, $parentItem){
                        //do sth.
                    },_canBeEnabled],null,
                    ['下发广播消息' ,function($itemScp, $parentItem){
                        //do sth.
                    },_canBeEnabled],null,
                    ['仪表盘' ,function($itemScp, $parentItem){
                        //do sth.
                    },_canBeEnabled],null,
                    ['下发广播消息' ,function($itemScp, $parentItem){
                        //do sth.
                    },_canBeEnabled]
                ];

                /**
                 * 二级菜单是否启用或禁用
                 * @param $itemScp      菜单所在指令的作用域
                 * @param $parentItem   上级菜单传入的对象
                 * @returns {boolean}   启用 true   禁用 false
                 * @private
                 */
                function _canBeEnabled($itemScp, $parentItem){
                    return true;
                }

                //获取到对应车辆数组
                var busArray = scope.busAttribution[busAttrKey];
                //为不同的菜单设置一个对应的header
                var menuHeaderDom = '<div class="menu-header '+ busAttrKey +' ">'+  scope.getBusAttrName(busAttrKey) +'</div>';
                var menuHeader = {
                    html : menuHeaderDom,
                    enabled : function(){ return false; }   //header在menu中不能被click
                };
                //如果对应数组中有车辆,这构建菜单数据
                //构建方法与结构详见:https://github.com/Templarian/ui.bootstrap.contextMenu
                if( busArray.length ){
                    for( var i = 0; i < busArray.length; i++ ){
                        var bus = busArray[i];
                        //这里需要向第二级菜单传递第一级菜单对象
                        var itemArray = [{ name : bus[ scope.busKeyMap.busNoKey ], data : bus },function($itemScope){
                        },secStepMenu];
                        menuArray.push(itemArray);
                    }
                    //将header插入至数组第一位,表示存在于menu的顶部
                    menuArray.splice(0,0,menuHeader);
                }
                return menuArray;
            };

            /**
             * 车辆菜单数据
             * null is the divider :P
             */
            scope.busMenuOptions = [
                ['设置报警样式',function($itemScp,$parentItem, $event){
                    //for testing style
                    console.log( $itemScp.bus );
                    angular.element($event.target).addClass('busAlarm busAlert');

                }],null,
                ['设置超载样式' ,function($itemScp, $parentItem, $event){
                    //for testing style
                    angular.element($event.target).addClass('busAlarm busFullLoad');

                }],null,
                ['设置超速样式' ,function($itemScp, $parentItem, $event){
                    //for testing style
                    angular.element($event.target).addClass('busAlarm busSpeeding');

                }],null,
                ['设置进站样式',function($itemScp,$parentItem, $event){
                    //for testing style
                    angular.element($event.target).addClass('busStationing');

                }],null,
                ['移除所有样式' ,function($itemScp, $parentItem, $event){
                    //for testing style
                    angular.element($event.target).removeClass('busAlarm busAlert busFullLoad busSpeeding busStationing');

                }],null,
                ['more',function($itemScp, $event, modelValue){
                },  [
                        ['sec menu 01' ,function($itemScp, $event, modelValue){

                        }],null,
                        ['sec menu 02' ,function($itemScp, $event, modelValue){

                        }]
                    ]

                ]
            ];
            //车辆菜单回调方法
            scope.busMenuAddCallback = function($itemScp, $event){
                angular.element($event.target).addClass('busActive');
                scope.$parent.$broadcast('zhx.ctc.layer.close');
            };
            scope.busMenuRemoveCallback = function(){
                angular.element('.ctc-linear-bus > li').removeClass('busActive');
            };

            /**
             * 车辆悬浮鼠标展示出车辆当前的一些信息
             * @param $event
             * @param busObject
             */
            /**
             * 点击打开车辆信息层
             * @param $event
             * @param busObject
             */
            scope.showBusInfo = function($event, busObject){
                var ev = $event || window.event;
                    ev.stopPropagation();
                    angular.element('.ctc-linear-bus > li').removeClass('busActive');
                    angular.element(ev.target).addClass('busActive');

                var busInfoScp = scope.$new();
                    busInfoScp.bus = busObject;
                var busInfoDom = $templateCache.get('zhx.ctc.bus.info.tpl.vicco');

                var layerOpts = {
                    event : ev,
                    dom : busInfoDom,
                    scope : busInfoScp,
                    autoClose : false,
                    addCallBack : function(){},
                    removeCallBack : function(){
                        angular.element('.ctc-linear-bus > li').removeClass('busActive');
                    }
                };

                var busInfoLayer = ctcService.createLayer(layerOpts);
                busInfoLayer.appendTo('body');
            };

            /**
             * 监控父控制器中的分屏状态, 分屏后,这个需要更新车辆判断相对位置的依据
             *
             */
            scope.$watch(function(){
                return mainCtroller.getColumnScreenState();
            },function(columnScreenState){
                //给模板用,模板某些DOM需要根据分屏状态来显示或隐藏部分内容
                scope.columnScreenState = !!columnScreenState;
                //更新在线车辆相对判断位置
                $timeout(function(){
                    ctcService.updateOnlineBusPos( scope.busAttribution, scope.busKeyMap, tElement);
                },100);

            });

            /**
             * 每一个直线图都应该监控传入的车辆对象数据BusData的变化,
             * 这里直接判断是否是该线路上的车,如果是的话,则进行车辆渲染;
             *
             * Every CTC has this watch method to observe busData;
             *
             */
            scope.$watch(function(){
                return mainCtroller.getBusData();
            },function(busData){
                if( busData.resData && busData.lineId ){
                    //这里传入的车辆数据首先需要判断是否为该线路下的车辆,如果属于的话,才进行车辆后续绘制处理
                    if( scope.lineId === busData[scope.lineKeyMap.lineIdKey] ){
                        mainCtroller.updateBus( busData.resData , scope.busAttribution, tElement );
                    }
                }

            });

            //为窗口绑定一个缩放事件,在缩放后,直线图上的车辆需要重新进行位置计算(仅计算相对位置)
            window.addEventListener('resize', function(){
                $timeout(function(){
                    ctcService.updateOnlineBusPos( scope.busAttribution, scope.busKeyMap, tElement);
                },100);
            });

        },
        templateUrl : 'zhx.multi.subCtc.tpl.vicco'
    }
}]);

/**
 * 扩展出原生 ng-right-click 右键事件
 */
ctcApp.directive("ngRightClick",['$parse',function($parse){
    return function(scope, element, attrs) {
        var fn = $parse(attrs.ngRightClick);
        element.bind('contextmenu', function(event) {
            scope.$apply(function() {
                event.preventDefault();
                fn(scope, {$event:event});
            });
        });
    };
}]);
 
})(); 